package com.cicdi.core.util;

import com.alaya.contracts.ppos.RestrictingPlanContract;
import com.alaya.contracts.ppos.abi.Function;
import com.alaya.contracts.ppos.dto.TransactionResponse;
import com.alaya.contracts.ppos.dto.resp.RestrictingPlan;
import com.alaya.contracts.ppos.utils.EncoderUtils;
import com.alaya.crypto.Credentials;
import com.alaya.parameters.NetworkParameters;
import com.alaya.protocol.Web3j;
import com.alaya.utils.Convert;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * 锁仓计划类工具
 *
 * @author haypo
 * @date 2020/12/3
 */
@Slf4j
public class RestrictUtil {
    private final SendUtil sendUtil;
    private final Web3j web3j;

    public RestrictUtil(String url) {
        sendUtil = new SendUtil(url);
        web3j = Web3j.build(sendUtil.web3jService);
    }

    /**
     * 给单个地址发布锁仓计划，速度较慢
     *
     * @param credentials         钱包
     * @param account             锁仓目的地址
     * @param restrictingPlanList 锁仓计划列表
     * @throws Exception io异常
     */
    public void createRestrictingPlanWithMidGasProvider(Credentials credentials, String account, List<RestrictingPlan> restrictingPlanList) throws Exception {
        for (RestrictingPlan restrictingPlan : restrictingPlanList) {
            BigDecimal atpAmount = Convert.fromVon(new BigDecimal(restrictingPlan.getAmount()), Convert.Unit.ATP);
            if (atpAmount.doubleValue() < Common.minRestrictAmount) {
                log.info("锁仓金额不能低于1atp");
                return;
            }
        }
        RestrictingPlanContract rpc = RestrictingPlanContract.load(web3j, credentials, NetworkParameters.CurrentNetwork.getChainId());
        TransactionResponse tr = rpc.createRestrictingPlan(account, restrictingPlanList, Common.MID_GAS_PROVIDER).send();
        log.info(tr.getTransactionReceipt().toString());
    }

    /**
     * 快速批量创建锁仓计划
     *
     * @param credentials         钱包
     * @param accountList         锁仓目的地址列表
     * @param restrictingPlanList 锁仓计划列表
     * @throws IOException io异常
     */
    public void fastCreateRestrictingPlan(Credentials credentials, List<String> accountList, List<RestrictingPlan> restrictingPlanList) throws IOException {
        for (RestrictingPlan restrictingPlan : restrictingPlanList) {
            BigDecimal atpAmount = Convert.fromVon(new BigDecimal(restrictingPlan.getAmount()), Convert.Unit.ATP);
            if (atpAmount.doubleValue() < Common.minRestrictAmount) {
                log.info("锁仓金额不能低于1atp");
                return;
            }
        }
        long nonce = NonceUtil.getNonce(web3j, credentials).longValue();
        for (String account : accountList) {
            fastCreateRestrictingPlan(credentials, account, restrictingPlanList, nonce++);
        }
    }

    /**
     * 快速创建锁仓计划
     *
     * @param credentials         钱包
     * @param account             锁仓地址
     * @param restrictingPlanList 锁仓计划列表
     * @param nonce               nonce值
     */
    public void fastCreateRestrictingPlan(Credentials credentials, String account, List<RestrictingPlan> restrictingPlanList, long nonce) {
        try {
            Function function = FunctionUtil.createRestrictingPlanFunction(account, restrictingPlanList);
            String data = EncoderUtils.functionEncoder(function);
            String toAddress = NetworkParameters.getPposContractAddressOfRestrctingPlan(NetworkParameters.CurrentNetwork.getChainId());
            sendUtil.fastSend(credentials, nonce, BigDecimal.ZERO, toAddress, data, Common.MID_GAS_PROVIDER);
            log.info("地址：{} 给地址：{} 创建锁仓计划",
                    credentials.getAddress(), account);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);
        }
    }
}
